#include "Task.hpp"
#include "Thread.hpp"
#include "RingQueue.hpp"

#include <string>
#include <vector>
#include <unistd.h>

using namespace ThreadModule;
// 给类填好模板，并重命名
using ringqueue_t = RingQueue<Task>;

// 创建线程
//func_t<ringqueue_t>，给函数填参数的类型（模板）
void InitComm(std::vector<Thread<ringqueue_t>> *threads, int num, ringqueue_t &rq, func_t<ringqueue_t> func, std::string who)
{
    for (int i = 0; i < num; i++)
    {
        std::string name = "thread-" + std::to_string(i + 1) + "-" + who;
        threads->emplace_back(func, rq, name);
    }
}

void Consumer(ringqueue_t &rq, std::string name)
{
    while (true)
    {
        sleep(2);

        Task t;
        rq.Pop(&t); // 取出任务

        t(); // 处理任务
        std::cout << "Consumer: [ " << name << " ]" << std::endl;
    }
}

void Productor(ringqueue_t &rq, std::string name)
{
    // 开始生产
    while (true)
    {
        rq.Enqueue(Download); // 放入任务
        std::cout << "Productor: [ " << name << " ]" << std::endl;
    }
}
void StartAll(std::vector<Thread<ringqueue_t>> &threads)
{
    for (auto &thread : threads)
    {
        std::cout << "start: " << thread.name() << std::endl;
        thread.Start();
    }
}
void InitProductor(std::vector<Thread<ringqueue_t>> *threads, int num, ringqueue_t &rq)
{
    InitComm(threads, num, rq, Productor, "Productor");
}

void InitConsumer(std::vector<Thread<ringqueue_t>> *threads, int num, ringqueue_t &rq)
{
    InitComm(threads, num, rq, Consumer, "Consumer");
}

void WaitAll(std::vector<Thread<ringqueue_t>> &threads)
{
    for (auto &thread : threads)
    {
        thread.Join();
    }
}
int main()
{
    // new 调用构造函数，创建一个上限为 10 的环形队列
    ringqueue_t *rq = new ringqueue_t(10);

    // 给线程传任务所需要的参数，并把线程放入数组管理起来
    std::vector<Thread<ringqueue_t>> threads;

    InitProductor(&threads, 3, *rq);
    InitConsumer(&threads, 5, *rq);

    StartAll(threads);

    WaitAll(threads);

    return 0;
}